home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 297_01 / prmanual.txt < prev    next >
Text File  |  1991-12-30  |  20KB  |  579 lines

  1. Feb 17 1989
  2. Revised July 22 1989
  3. Revised December 25 1991
  4. Revised January 1 1992
  5.  
  6.  
  7.         Small Prolog User Guide & Reference
  8. Introduction.
  9. -------------
  10. Small Prolog is a public domain implementation of the Prolog Language, with
  11. C source provided.
  12.  
  13. You can do what you like with the code, save claim it as your own work.
  14. If you embed this into a commercial application I would nevertheless
  15. appreciate a free copy of your software.
  16.  
  17.  There are other public domain implementations around, but I dont know of 
  18. one where you get the C code apart a public domain compiler called 
  19. Stony Brook Prolog, but it hasnt yet been ported to the PC.
  20.  
  21. The design goals were:
  22.     A minimal usable implementation.
  23.     Maximum portability.
  24.     Educational code.
  25.     Extensibility.
  26.     A small object code.
  27.     Embeddability.
  28.     Facilitate meta-programming.
  29. Of course these goals have not been fully met!
  30. It helps to read Hogger's book "An introduction to logic programming"
  31.  (Academic Press 1984)
  32. to  understand the code. You could also try
  33. Maier & Warren's "Computing with logic" - Benjamin Cummings Ed. 
  34. 1988 as an alternative.
  35.  
  36. On the negative side:
  37.  The syntax is LISP-like which has its advantages for meta-programming
  38. and small code, but I find that it is not very friendly.
  39.  
  40.  There is no garbage collection of any sort. It's surprising how far
  41. you can get away with this. If you want to garbage collect on the
  42. heap, then I suggest that you make a separate zone for pairs and 
  43. modify get_node() so that it in fact allocates a pair but only 
  44. returns the head. Then adapt the garbage collector of the  source code
  45. of Xlisp (which is public domain). 
  46.   You could also garbage collect some of the substitution stack. The
  47. only easily available literature I know of is an article by Maurice
  48. Bruynehooge in "Implementations of Prolog" edited by John Campbell,
  49. published by John Wiley. The book is full of typos, so good luck.
  50.  
  51.  There are quite a few improvements to the code to be made (at this time)
  52. such as last call optimisation.
  53.  
  54.  The trace facilities of version 2 are no longer minimal.
  55.  
  56.  Not all the "standard" builtins have been included. 
  57.  We thought you would enjoy putting these in. 
  58.  
  59. Syntax
  60. ------
  61.  The syntax of the prolog is extremely simple. You can look 
  62.  at one of the prolog source files (*.spr) provided to get an idea 
  63.  or you can look at the C souce code, or you can read the following:
  64.  
  65.  Comments are as in the C language:
  66.  /* This is a comment 
  67.   */
  68.  
  69.  The program may be layed out with as many spaces, line_feeds and
  70.  tabs as you like providing you don't chop a lexical item in two.
  71.  A lexical item is an identifier or a number or a string or 
  72.  brackets or the vertical bar.
  73.  
  74.  Although strictly speaking a program is a set of clauses
  75.  AND a query, we shall call a set of clauses a program.
  76.  
  77. The following is a context free grammar for the  syntax.
  78. Nonterminals are distinguished from terminals by putting them
  79. inside angle brackets. Comments follow the rewrite rules and are
  80. inside /* */.
  81.  
  82. <program> -> <empty>
  83. <program> -> <clause> <program>
  84.  
  85. <clause> -> <rule>
  86. <clause> -> <fact>
  87.  
  88. <rule> -> (<head> <goals>)
  89.  
  90. <fact> -> (<head>)
  91. <fact> -> <head>            /* alternative */
  92.  
  93. <head> -> (<clause predicate> <arguments>)
  94. <head> -> (<clause predicate> <arguments>|<argument>)
  95. /* use the second kind of head with caution */
  96.  
  97. <clause predicate> -> <atom other than builtin>
  98.  
  99. <arguments> -> <empty>
  100. <arguments> -> <argument><arguments>
  101.  
  102. <argument> -> <atom>
  103. <argument> -> <list>
  104. <argument> -> <integer>
  105. <argument> -> <real>            /* depends on conditional compilation */
  106. <argument> -> <string>
  107. <argument> -> <variable>
  108. <argument> -> <char>            /* depends on conditional compilation */
  109.  
  110. <atom> -> ()
  111. /* you can space the brackets out */
  112. <atom> -> <small letter><identifier tail>
  113.  
  114. <variable> -> _
  115. <variable> -> _<identifier tail>
  116. <variable> -> <capital_letter><identifier tail>
  117.  
  118. <identifier tail> -> <empty>
  119. <identifier tail> -> <character other than space,bracket,quote or bar>
  120. <identifier tail> -> <identifier tail><identifier tail>
  121.  
  122. <list> -> (<arguments>)
  123. <list> -> (<arguments>|<argument>)
  124.  
  125. <integer> -> <sign><unsigned integer>
  126. <integer> -> <unsigned integer>
  127.  
  128. <unsigned integer> -> <digit>
  129. <unsigned integer> -> <digit><unsigned integer>
  130.  
  131. <sign> -> -
  132. <sign> -> <empty>
  133.  
  134. <goals> -> <goal>
  135. <goals> -> <goal><space><goals>
  136.  
  137. <goal> -> (<predicate><space><arguments>)
  138. <goal> -> (<predicate><space><arguments>|<argument>)
  139. /* dont use this form if the predicate is builtin */
  140.  
  141. <predicate> -> <small letter><identifier tail>
  142.  
  143. <real>-><integer>.<unsigned integer>
  144.  
  145. <string> -> <string quote> <sequence of characters> <string quote>
  146. /* Dont put a string quote in the sequence of characters unless it is
  147.  * immediately followed by another string quote -only one is considered.
  148.  * 
  149.  */
  150.  
  151. <char> -> '<printable character>'
  152. <char> -> '\n'
  153. <char> -> '\r'
  154. <char> -> '\t'
  155. <char> -> '\v'
  156. <char> -> '\f'
  157. <char> -> '\''
  158. <char> -> '\"'
  159. <char> -> '\<octal digit>'
  160. <char> -> '\<octal digit><octal digit>'
  161. <char> -> '\<octal digit><octal digit><octal digit>'
  162.  
  163. <query> -> (<goals>)
  164. <query> -> <goal>
  165. /* The last form is permitted for one goal-queries */
  166.  
  167. <string quote> -> "
  168.  
  169. /* END OF GRAMMAR */
  170.  
  171. Now for 4 sample queries. You don't type the "?-".
  172. ?-((writes "Hello, world")(nl))
  173. ?-((nl))
  174. ?-(space_left Heap Strings Dyn SUb Trail Temp)
  175. ?-((writes "What is your name?")(read X)
  176.  (writes "Hello, ")(display X))
  177. ?-(writes "This :"" is an embeded double quote")
  178.  
  179.  
  180. Builtins:
  181. ---------
  182. Builtins are predefined predicates that in fact call on C code.
  183. The builtins are documented in the source file prbltin.c.
  184. The file help.spr provides "on line" documentation.
  185.  
  186. You could add more builtins by imitating that file, but 
  187. we suggest using an extra file.
  188. You should try to be consistent with Clocksin and Mellish's 
  189. builtins (see bibliography). Of course it's not as interesting 
  190. trying to define predicates like "functor", "arg" and "univ".
  191.  
  192. To add your own builtins you should know the following:
  193.  
  194. Small Prolog uses many global variables defined in prlush.c
  195. "Arguments" is the list of arguments of the current goal and "SubstGoal"
  196.  is the (substitution) environment for this. To get at the different 
  197. elements of "Arguments" you can use the ARG_XXX macros in prbltin.h.
  198. All functions make frequent use of the dereference() function in 
  199. prunify.c so it is important to understand this as soon as you have
  200. understood the basic data types. This function dereferences a
  201. term in an environment and updates the globals DerefNode and 
  202. DerefSubst which represent the resulting derefenced object. 
  203. They are globals.
  204.  
  205. The following scheme gives you an idea of how a builtin might be
  206. built.
  207.  
  208. Pmybuiltin()
  209. {
  210. /* local variables used below */
  211. int result;
  212. integer i;
  213. char *s;...
  214.  
  215. /* argument extaction macros */
  216. ARG_INT(1,i) /* the first arg expected is an INT, i is set to this */
  217. ARG_STRING(2,s); /* the second arg expected is a string */
  218. ...
  219.  
  220. result = my_function(i,s,...,&o,...);/* you define this */
  221. bind_...(3,o); /* the third argument is bound to "o" */
  222.  
  223. if(result == MY_SUCCESS/* you define this */)return 1;
  224. if(result == MY_FAIL/* ditto */)return 0;
  225. else
  226.   return(CRASH);/* force a stack dump */
  227. }
  228.  
  229. Calling a builtin with extra arguments is harmless - they are
  230. just ignored. Missing arguments or arguments of a wrong type
  231. generally force a "stack dump" so you know where the program
  232. was when it crashed. This is a print out of all pending goal lists
  233. of the ancestors of the current goal.
  234. The top-most goal list is the list of goals of the current clause.
  235. Underneath this are the goals of the clause that called that etc.
  236.  
  237. From version 2 on a builtin may backtrack by making the related 
  238. function return ND_SUCCESS. The repeat builtin does this.
  239. It is the builtin's responsability to update ND_builtin_next_nodeptr
  240. when it is called. That value is restored on backtracking and
  241. is the only information that is saved from one call to the next.
  242. See how the gennum predicate is implemented.
  243.  
  244. Input-output:
  245. -------------
  246. The i